//
//  NetManager.m
//  KingSelected
//
//  Created by 杨鹏 on 2023/10/27.
//

#import "NetManager.h"

BOOL AppHasNetwork = YES;
NSString *kHttpErrorReason = @"httpError";

@implementation NetManager

+ (void)requestWithUrl:(NSString *)urlString httpMethod:(HttpMethod)httpMethod parameters:(id _Nullable)parameters success:(nonnull SuccessBlock)success failure:(nonnull FailureBlock)failure {
    [self requestWithUrl:urlString httpMethod:httpMethod parameters:parameters needEncryption:NO needExtraProcess:NO success:success failure:failure];
}

/// 网络请求,
+ (void)requestWithUrl:(NSString *)urlString httpMethod:(HttpMethod)httpMethod parameters:(id _Nullable)parameters needEncryption:(BOOL)needEncryption success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self requestWithUrl:urlString httpMethod:httpMethod parameters:parameters needEncryption:needEncryption needExtraProcess:NO success:success failure:failure];
}

/// post网络请求,是否加密
+ (void)postWithUrl:(NSString *)urlString parameters:(id _Nullable)parameters needEncryption:(BOOL)needEncryption success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self requestWithUrl:urlString httpMethod:HttpMethodPOST parameters:parameters needEncryption:needEncryption needExtraProcess:NO success:success failure:failure];
}

/// post网络请求,是否加密
+ (void)postWithUrl:(NSString *)urlString parameters:(id _Nullable)parameters needEncryption:(BOOL)needEncryption needExtraProcess:(BOOL)needExtraProcess success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self requestWithUrl:urlString httpMethod:HttpMethodPOST parameters:parameters needEncryption:needEncryption needExtraProcess:needExtraProcess success:success failure:failure];
}

+ (void)getWithUrl:(NSString *)urlString parameters:(id _Nullable)parameters needEncryption:(BOOL)needEncryption needExtraProcess:(BOOL)needExtraProcess success:(SuccessBlock)success failure:(FailureBlock)failure {
    [self requestWithUrl:urlString httpMethod:HttpMethodGET parameters:parameters needEncryption:needEncryption needExtraProcess:needExtraProcess success:success failure:failure];
}

/// 网络请求
+ (void)requestWithUrl:(NSString *)urlString httpMethod:(HttpMethod)httpMethod parameters:(id _Nullable)parameters needEncryption:(BOOL)needEncryption needExtraProcess:(BOOL)needExtraProcess success:(nonnull SuccessBlock)success failure:(nonnull FailureBlock)failure {
    NSDictionary *httpHeader = [self builderHttpHeader];
    NSDictionary *httpBody = parameters;
    [self requestLogPrint:urlString httpHeader:httpHeader parameters:parameters];
    [self httpRequestWithUrl:urlString httpMethod:httpMethod httpHeader:httpHeader httpBody:httpBody progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self responseLogPrint:task.response.URL.absoluteString responseData:responseObject];
        if (![responseObject isKindOfClass:[NSDictionary class]]) {
            [self requestFailureWithMsg:nil code:-1 block:failure];
            return;
        }
        if (needExtraProcess) {
            if (success) {
                success(responseObject);
            }
        }else {
            NSDictionary *dic = (NSDictionary *)responseObject;
            if (dic[@"code"] == nil) {
                if (success) {
                    success(dic[@"result"]);
                }
                return;
            }
            int code = [dic[@"code"] intValue];
            if (code == 200) {
                if (success) {
                    success(dic[@"result"]);
                }
            } else {
                [self requestFailureWithMsg:dic[@"message"] code:code block:failure];
            }
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self errorLogPrint:error];
        NSError *bitchError = [self errorInfoHandle:error];
        if (bitchError.code == 401) {
            [kUserAccount logout];
        }else {
            if (failure) {
                failure(bitchError);
            }
        }
    }];
}

/// 上传文件
/// @param urlString utl
/// @param parameters 参数
/// @param fileDataArr 文件数据数组
/// @param fileNames 文件名数组
/// @param mimeType 文件类型
/// @param progress 进度
/// @param success 成功
/// @param failure 失败
+ (void)uploadWithURL:(NSString *)urlString
           parameters:(id _Nullable)parameters
             fileData:(NSArray *)fileDataArr
            fileNames:(NSArray *_Nullable)fileNames
             mimeType:(NSString *_Nullable)mimeType
             progress:(nonnull ProgresBlock)progress
              success:(nonnull SuccessBlock)success
              failure:(nonnull FailureBlock)failure {
    NSDictionary *httpHeader = [self builderHttpHeader];
    NSDictionary *httpBody = parameters;
    [self requestLogPrint:urlString httpHeader:httpHeader parameters:parameters];
    [NetworkServer uploadWithURL:urlString
                         httpHeader:httpHeader
                           httpBody:httpBody
                           fileData:fileDataArr
                          fileNames:fileNames
                           mimeType:mimeType
                           progress:progress
                            success:^(NSURLSessionDataTask *task, id responseObject) {
                                [self responseLogPrint:task.response.URL.absoluteString responseData:responseObject];
                                
                                if (![responseObject isKindOfClass:[NSDictionary class]]) {
                                    [self requestFailureWithMsg:nil code:-1 block:failure];
                                    return;
                                }
                                NSDictionary *dic = (NSDictionary *)responseObject;
                                int code = [dic[@"code"] intValue];
                                if (code == 200) {
                                    if (success) {
                                        success(dic[@"result"]);
                                    }
                                }else {
                                    [self requestFailureWithMsg:dic[@"message"] code:code block:failure];
                                }
                            }
                            failure:^(NSURLSessionDataTask *task, NSError *error) {
                                [self errorLogPrint:error];
                                
                                NSError *bitchError = [self errorInfoHandle:error];
                                if (error.code == 401) {
                                    [kUserAccount logout];
                                }else {
                                    if (failure) {
                                        failure(bitchError);
                                    }
                                }
                            }];
}

+ (void)httpRequestWithUrl:(NSString *)urlString
                httpMethod:(HttpMethod)httpMethod
                httpHeader:(NSDictionary *)httpHeader
                  httpBody:(NSDictionary *)httpBody
                  progress:(void (^)(NSProgress *))progress
                   success:(RequestSuccessBlock)success
                   failure:(RequestFailureBlock)failure {
    switch(httpMethod){
        case HttpMethodGET:
            [NetworkServer getWithUrl:urlString httpHeader:httpHeader httpBody:httpBody progress:progress success:success failure:failure];
            break;
        case HttpMethodPOST:
            [NetworkServer postWithUrl:urlString httpHeader:httpHeader httpBody:httpBody progress:progress success:success failure:failure];
            break;
        case HttpMethodPUT:
            break;
        case HttpMethodDELETE:
            break;
        case HttpMethodHEAD:
            break;
        case HttpMethodPATCH:
            break;
        default:
            break;
    }
}

#pragma mark - 请求头、请求体的参数处理、加密及签名
/// 生成HttpHeader参数
+ (NSDictionary *)builderHttpHeader {
    NSMutableDictionary *sysInfoDic = [[NSMutableDictionary alloc] init];
    if (kUserAccount.token.length > 10) {
        sysInfoDic[@"Token"] = kUserAccount.token;
    }
    if (kUserAccount.user.id.length > 0) {
        sysInfoDic[@"Uid"] = kUserAccount.user.id;
    }
    return sysInfoDic;
}

#pragma mark - 打印url、请求及响应参数、error
+ (void)requestLogPrint:(NSString *)urlString httpHeader:(NSDictionary *)httpHeader parameters:(NSDictionary *)parameters {
    NSLog(@"\ncurrent Thread: %@  \nRequest URL: %@  \nHttp Header: %@  \nparameters: %@", [NSThread currentThread], urlString, httpHeader, parameters);
}

+ (void)responseLogPrint:(NSString *)urlString responseData:(NSDictionary *)responseData {
    NSLog(@"\ncurrent Thread: %@  \nResponse URL: %@  \nResponse Data: %@", [NSThread currentThread], urlString, responseData);
}

+ (void)errorLogPrint:(NSError *)error {
    NSLog(@"\ncurrent Thread: %@  \nURL: %@  \nerror code: %zd  \ndescription: %@", [NSThread currentThread], error.userInfo[NSURLErrorFailingURLErrorKey], error.code, error.localizedDescription);
}

/// 请求失败的信息转换为提示error
+ (void)requestFailureWithMsg:(NSString *)msg code:(NSInteger)code block:(void (^)(NSError *error))failure {
    if ([msg isKindOfClass:[NSNull class]]) {
        msg = nil;
    }
    if (code == 401) {
        [kUserAccount logout];
    }else {
        NSError *error = [NSError errorWithDomain:@"选品王" code:code userInfo:@{kHttpErrorReason : msg ?: @"网络连接失败,请稍后再试~"}];
        if (failure) {
            failure(error);
        }
    }
}

#pragma mark - 错误处理
+ (NSError *)errorInfoHandle:(NSError *)error {
    NSDictionary *userInfo = nil;
    NSInteger code = error.code;
    
    if (error.code == -1012 || error.code == 3840) {
        userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
    }
    if (error.code == -1011) { //codeNumber == 500  404(找不到地址) 405(方法错误)  401(未授权)
        NSHTTPURLResponse * response = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.response"];
        NSInteger codeNumber = response.statusCode;
        if (codeNumber == 404){
            userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
        }else if (codeNumber == 405){
            userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
        }else if (codeNumber == 401){
            userInfo = @{kHttpErrorReason : @"登录过期咯~"};
            [kUserAccount logout];
        }else{
            userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
        }
        code = codeNumber;
    }
    if (error.code == -1009) {
        userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
    }
    if (error.code == -1004) {
        userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
    }
    if (error.code == -1001) {
        userInfo = @{kHttpErrorReason : @"网络连接失败,请稍后再试~"};
    }
    if (userInfo == nil) {
        userInfo = @{kHttpErrorReason : error.localizedDescription};
    }
    NSError *bitchError = [NSError errorWithDomain:@"选品王" code:code userInfo:userInfo];
    return bitchError;
}

@end
